-
Notifications
You must be signed in to change notification settings - Fork 17
feat(useSetting): sync values with LS and store in api #3111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the settings synchronization architecture by moving the sync logic from useEffect hooks in useSetting.ts to RTK Query's onQueryStarted lifecycle hooks in the API layer. The main goal is to centralize settings synchronization between localStorage, Redux store, and the meta settings API.
Key Changes:
- Consolidates all settings sync logic into the
settingsApiendpoints'onQueryStartedhooks - Simplifies
useSettinghook by removing multipleuseEffectdependencies - Handles localStorage and API settings synchronization at the API layer instead of component layer
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
src/store/reducers/settings/utils.ts |
Adds helper functions getSettingDefault and shouldSyncSettingToLS to support centralized settings sync logic |
src/store/reducers/settings/useSetting.ts |
Removes all useEffect-based sync logic and simplifies hook to only trigger API queries and mutations |
src/store/reducers/settings/constants.ts |
Updates SETTINGS_OPTIONS type to explicitly allow undefined values for better type safety |
src/store/reducers/settings/api.ts |
Implements comprehensive sync logic in onQueryStarted hooks for both query and mutation endpoints, handling localStorage and store updates |
src/services/api/metaSettings.ts |
Updates return type to allow undefined for settings that don't exist in the backend |
|
@greptile-review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8 files reviewed, 2 comments
|
|
||
| return {data}; | ||
| } catch (error) { | ||
| console.error('Cannot get settings:', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be that error is "Cannot get setting" - but the real situation is that one of patches failed ?
|
Now as I see we have three sources of truth:
And we struggle to keep all of them in sync |
Yes, everything is to keep them in sync |
Is it a goal or temporary state? |
It's a goal |
| const newValue = data ?? {name, user}; | ||
|
|
||
| // Try to sync local value if there is no backend value | ||
| syncLocalValueToMetaIfNoData(newValue, dispatch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible that null/undefined on backend is intentional?
i mean we removed some setting for example
but LS has some old value (in another browser for example) and pushes this setting to backend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a current limitation, yes. We cannot have null or undefined as backend value, there should be at least something, otherwise defined localStorage value will be loaded to backend. Without this it's unclear, when we should sync local value to backend
| return; | ||
| } | ||
|
|
||
| const localValue = localStorage.getItem(params.name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we use localStorage directly here but there are already functions for this like
readSettingValueFromLS / shouldSyncSettingToLS
these functions as I may suppose were created to make work with LS somehow guarded
I thought this over again and came to a conclusion that actually there is one source of truth (backend) while LS and rtq storage are used as caches for interface rensponsiveness so actually its not "three sources of truth" but "one with two caches" Does it make sense? |
In general, you are right. But it depends on app installation. There are 3 cases.
So, preload data from LS to store, load actual value from meta when request is finished.
In all cases redux is used as sync cache for data. |
|
So there are two main scenarios with mainly opposite mechanics
It appears we try to handle both at once with one handler and therefore it looks a bit complex I'm trying to imagine if we could explicitly split these scenarios for clarity and maintainability its possible to postpone this and separate to some tech issue but would be great if we could handle it at once |
Part of #2892
Currently it can be checked with table columns width.
Stand (without meta): https://nda.ya.ru/t/BEIjuuLI7N8Qd7
Stand (with meta): https://nda.ya.ru/t/Y60-A5AI7NF3Mi
Sync all values within api
onQueryStartedinstead of useEffects.This approach proved itself good with and without meta api. Without meta api there is only 1 failed test (against 100-200 before): #3054
greptile-review
CI Results
Test Status:⚠️ FLAKY
📊 Full Report
Test Changes Summary ⏭️2
⏭️ Skipped Tests (2)
Bundle Size: ✅
Current: 66.13 MB | Main: 66.13 MB
Diff: +2.99 KB (0.00%)
✅ Bundle size unchanged.
ℹ️ CI Information